{
 "cells": [
  {
   "cell_type": "markdown",
   "source": [
    "# 使用LLM模型结合RAG优化Text2SQL的应用程序\n",
    "\n",
    "## 1.准备环境变量.env"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "f3d45451790b41f5"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "bge-large-zh-v1.5\n",
      "API_BASE_URL: https://cognihubemp.baystoneai.com/cognihub/service\n"
     ]
    }
   ],
   "source": [
    "from dotenv import load_dotenv\n",
    "import os\n",
    "\n",
    "# 加载 .env 文件\n",
    "load_dotenv()\n",
    "\n",
    "# 读取环境变量\n",
    "API_BASE_URL = os.getenv(\"API_BASE_URL\")\n",
    "API_KEY = os.getenv(\"API_KEY\")\n",
    "langsmith_api_key = os.getenv(\"LANGSMITH_API_KEY\")\n",
    "EMBEDDER_URL = os.getenv(\"EMBEDDER_URL\")\n",
    "EMBEDDER_MODEL = os.getenv(\"EMBEDDER_MODEL\")\n",
    "print(EMBEDDER_MODEL)\n",
    "print(\"API_BASE_URL:\", API_BASE_URL)"
   ],
   "metadata": {
    "collapsed": true,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:01.435471Z",
     "start_time": "2024-11-11T06:53:01.424403Z"
    }
   },
   "id": "initial_id",
   "execution_count": 39
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 2.准备LLM模型"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "bf94d204e8e7688d"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "from langchain_openai import ChatOpenAI\n",
    "\n",
    "CHAT_MODEL = \"qwen2.5-instruct\"\n",
    "llm = ChatOpenAI(\n",
    "    model=CHAT_MODEL,\n",
    "    base_url=f'{API_BASE_URL}/v1',\n",
    "    api_key=API_KEY,\n",
    "    temperature=0,\n",
    "    streaming=False\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:01.573756Z",
     "start_time": "2024-11-11T06:53:01.439596Z"
    }
   },
   "id": "5cac53f2db23d159",
   "execution_count": 40
  },
  {
   "cell_type": "markdown",
   "source": [
    "## 3.询问简单的问题"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "ec245e6345d0be75"
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new SQLDatabaseChain chain...\u001B[0m\n",
      "总共有多少员工?\n",
      "SQLQuery:\u001B[32;1m\u001B[1;3mSQLQuery: SELECT COUNT(*) FROM \"Employee\"\u001B[0m\n",
      "SQLResult: \u001B[33;1m\u001B[1;3m[(8,)]\u001B[0m\n",
      "Answer:\u001B[32;1m\u001B[1;3m总共有8名员工。\u001B[0m\n",
      "\u001B[1m> Finished chain.\u001B[0m\n"
     ]
    },
    {
     "data": {
      "text/plain": "{'query': '总共有多少员工?', 'result': '总共有8名员工。'}"
     },
     "execution_count": 41,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from langchain.utilities import SQLDatabase\n",
    "from langchain_experimental.sql import SQLDatabaseChain\n",
    "\n",
    "db = SQLDatabase.from_uri(\"sqlite:///./db/Chinook.db\")\n",
    "db_chain = SQLDatabaseChain.from_llm(llm, db, verbose=True)\n",
    "\n",
    "db_chain.invoke(\"总共有多少员工?\")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:07.057566Z",
     "start_time": "2024-11-11T06:53:01.576579Z"
    }
   },
   "id": "df24fa8d2caed5ba",
   "execution_count": 41
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "few_shots = {\n",
    "    \"List all artists.\": \"SELECT * FROM artists;\",\n",
    "    \"Find all albums for the artist 'AC/DC'.\": \"SELECT * FROM albums WHERE ArtistId = (SELECT ArtistId FROM artists WHERE Name = 'AC/DC');\",\n",
    "    \"连续两个月都下订单的客户有哪些?\":\"SELECT DISTINCT a.'CustomerId', a.'FirstName', a.'LastName' FROM 'Customer' a JOIN 'Invoice' b ON a.'CustomerId' = b.'CustomerId' JOIN 'Invoice' c ON a.'CustomerId' = c.'CustomerId' AND ((strftime('%Y-%m', b.'InvoiceDate') = strftime('%Y-%m', date(c.'InvoiceDate', '-1 month'))) OR (strftime('%Y-%m', b.'InvoiceDate') = strftime('%Y-%m', date(c.'InvoiceDate', '+1 month'))))\"\n",
    "}"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:07.067671Z",
     "start_time": "2024-11-11T06:53:07.060168Z"
    }
   },
   "id": "22c300da01ab83ff",
   "execution_count": 42
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 4.构建RAG检索器"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "ca47da92121d2334"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "from langchain.schema import Document\n",
    "from langchain_community.vectorstores import Chroma\n",
    "from langchain_community.embeddings import XinferenceEmbeddings\n",
    "\n",
    "\n",
    "\n",
    "few_shot_docs = [\n",
    "    Document(page_content=question, metadata={\"sql_query\": few_shots[question]})\n",
    "    for question in few_shots.keys()\n",
    "]\n",
    "vectorstore = Chroma.from_documents(\n",
    "    documents=few_shot_docs,\n",
    "    collection_name=\"rag-chroma\",\n",
    "    embedding=XinferenceEmbeddings(server_url=EMBEDDER_URL, model_uid=EMBEDDER_MODEL),\n",
    ")\n",
    "retriever = vectorstore.as_retriever()"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:07.850794Z",
     "start_time": "2024-11-11T06:53:07.073025Z"
    }
   },
   "id": "dbf9cf0eb1009b13",
   "execution_count": 43
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 5.构建SQL 工具链"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "ac2c6f10acea0327"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "from langchain.agents.agent_toolkits import create_retriever_tool\n",
    "# description注意要加 in Chinese,使用中文检索,切记!\n",
    "tool_description = \"\"\"\n",
    "This tool will help you understand similar examples to adapt them to the user question in Chinese.\n",
    "Input to this tool should be the user question.\n",
    "\"\"\"\n",
    "\n",
    "retriever_tool = create_retriever_tool(\n",
    "    retriever, name=\"sql_get_similar_examples\", description=tool_description\n",
    ")\n",
    "custom_tool_list = [retriever_tool]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:07.866641Z",
     "start_time": "2024-11-11T06:53:07.854497Z"
    }
   },
   "id": "87d1671046a95692",
   "execution_count": 44
  },
  {
   "cell_type": "markdown",
   "source": [
    "### 6.构建SQL Agent"
   ],
   "metadata": {
    "collapsed": false
   },
   "id": "564e1bae23feeb39"
  },
  {
   "cell_type": "code",
   "outputs": [],
   "source": [
    "from langchain.agents import AgentType, create_sql_agent\n",
    "from langchain_community.agent_toolkits import SQLDatabaseToolkit\n",
    "\n",
    "toolkit = SQLDatabaseToolkit(db=db, llm=llm)\n",
    "\n",
    "# 注意要加 in Chinese,使用中文检索,切记!\n",
    "custom_suffix = \"\"\"\n",
    "I should first get the similar examples in Chinese I know.\n",
    "If the examples are enough to construct the query, I can build it.\n",
    "Otherwise, I can then look at the tables in the database to see what I can query.\n",
    "Then I should query the schema of the most relevant tables\n",
    "\"\"\"\n",
    "\n",
    "agent = create_sql_agent(\n",
    "    llm=llm,\n",
    "    toolkit=toolkit,\n",
    "    verbose=True,\n",
    "    agent_type=AgentType.OPENAI_FUNCTIONS,\n",
    "    extra_tools=custom_tool_list,\n",
    "    suffix=custom_suffix,\n",
    ")"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:07.991571Z",
     "start_time": "2024-11-11T06:53:07.873328Z"
    }
   },
   "id": "c835a906bf15593f",
   "execution_count": 45
  },
  {
   "cell_type": "code",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "\n",
      "\u001B[1m> Entering new SQL Agent Executor chain...\u001B[0m\n"
     ]
    },
    {
     "ename": "AssertionError",
     "evalue": "",
     "output_type": "error",
     "traceback": [
      "\u001B[0;31m---------------------------------------------------------------------------\u001B[0m",
      "\u001B[0;31mAssertionError\u001B[0m                            Traceback (most recent call last)",
      "Cell \u001B[0;32mIn[46], line 1\u001B[0m\n\u001B[0;32m----> 1\u001B[0m \u001B[43magent\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43minvoke\u001B[49m\u001B[43m(\u001B[49m\u001B[43m{\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43minput\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43m连续两个月都下订单的客户有哪些?\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m}\u001B[49m\u001B[43m)\u001B[49m\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain/chains/base.py:170\u001B[0m, in \u001B[0;36mChain.invoke\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m    168\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m    169\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_chain_error(e)\n\u001B[0;32m--> 170\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m e\n\u001B[1;32m    171\u001B[0m run_manager\u001B[38;5;241m.\u001B[39mon_chain_end(outputs)\n\u001B[1;32m    173\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m include_run_info:\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain/chains/base.py:160\u001B[0m, in \u001B[0;36mChain.invoke\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m    157\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m    158\u001B[0m     \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_validate_inputs(inputs)\n\u001B[1;32m    159\u001B[0m     outputs \u001B[38;5;241m=\u001B[39m (\n\u001B[0;32m--> 160\u001B[0m         \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_call\u001B[49m\u001B[43m(\u001B[49m\u001B[43minputs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mrun_manager\u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m    161\u001B[0m         \u001B[38;5;28;01mif\u001B[39;00m new_arg_supported\n\u001B[1;32m    162\u001B[0m         \u001B[38;5;28;01melse\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_call(inputs)\n\u001B[1;32m    163\u001B[0m     )\n\u001B[1;32m    165\u001B[0m     final_outputs: Dict[\u001B[38;5;28mstr\u001B[39m, Any] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mprep_outputs(\n\u001B[1;32m    166\u001B[0m         inputs, outputs, return_only_outputs\n\u001B[1;32m    167\u001B[0m     )\n\u001B[1;32m    168\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain/agents/agent.py:1629\u001B[0m, in \u001B[0;36mAgentExecutor._call\u001B[0;34m(self, inputs, run_manager)\u001B[0m\n\u001B[1;32m   1627\u001B[0m \u001B[38;5;66;03m# We now enter the agent loop (until it returns something).\u001B[39;00m\n\u001B[1;32m   1628\u001B[0m \u001B[38;5;28;01mwhile\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_should_continue(iterations, time_elapsed):\n\u001B[0;32m-> 1629\u001B[0m     next_step_output \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_take_next_step\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m   1630\u001B[0m \u001B[43m        \u001B[49m\u001B[43mname_to_tool_map\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1631\u001B[0m \u001B[43m        \u001B[49m\u001B[43mcolor_mapping\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1632\u001B[0m \u001B[43m        \u001B[49m\u001B[43minputs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1633\u001B[0m \u001B[43m        \u001B[49m\u001B[43mintermediate_steps\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1634\u001B[0m \u001B[43m        \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mrun_manager\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1635\u001B[0m \u001B[43m    \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m   1636\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(next_step_output, AgentFinish):\n\u001B[1;32m   1637\u001B[0m         \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_return(\n\u001B[1;32m   1638\u001B[0m             next_step_output, intermediate_steps, run_manager\u001B[38;5;241m=\u001B[39mrun_manager\n\u001B[1;32m   1639\u001B[0m         )\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain/agents/agent.py:1335\u001B[0m, in \u001B[0;36mAgentExecutor._take_next_step\u001B[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001B[0m\n\u001B[1;32m   1326\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_take_next_step\u001B[39m(\n\u001B[1;32m   1327\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m   1328\u001B[0m     name_to_tool_map: Dict[\u001B[38;5;28mstr\u001B[39m, BaseTool],\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m   1332\u001B[0m     run_manager: Optional[CallbackManagerForChainRun] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m   1333\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Union[AgentFinish, List[Tuple[AgentAction, \u001B[38;5;28mstr\u001B[39m]]]:\n\u001B[1;32m   1334\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_consume_next_step(\n\u001B[0;32m-> 1335\u001B[0m         \u001B[43m[\u001B[49m\n\u001B[1;32m   1336\u001B[0m \u001B[43m            \u001B[49m\u001B[43ma\u001B[49m\n\u001B[1;32m   1337\u001B[0m \u001B[43m            \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43ma\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_iter_next_step\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m   1338\u001B[0m \u001B[43m                \u001B[49m\u001B[43mname_to_tool_map\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1339\u001B[0m \u001B[43m                \u001B[49m\u001B[43mcolor_mapping\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1340\u001B[0m \u001B[43m                \u001B[49m\u001B[43minputs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1341\u001B[0m \u001B[43m                \u001B[49m\u001B[43mintermediate_steps\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1342\u001B[0m \u001B[43m                \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1343\u001B[0m \u001B[43m            \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m   1344\u001B[0m \u001B[43m        \u001B[49m\u001B[43m]\u001B[49m\n\u001B[1;32m   1345\u001B[0m     )\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain/agents/agent.py:1335\u001B[0m, in \u001B[0;36m<listcomp>\u001B[0;34m(.0)\u001B[0m\n\u001B[1;32m   1326\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21m_take_next_step\u001B[39m(\n\u001B[1;32m   1327\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m   1328\u001B[0m     name_to_tool_map: Dict[\u001B[38;5;28mstr\u001B[39m, BaseTool],\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m   1332\u001B[0m     run_manager: Optional[CallbackManagerForChainRun] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m   1333\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Union[AgentFinish, List[Tuple[AgentAction, \u001B[38;5;28mstr\u001B[39m]]]:\n\u001B[1;32m   1334\u001B[0m     \u001B[38;5;28;01mreturn\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_consume_next_step(\n\u001B[0;32m-> 1335\u001B[0m         \u001B[43m[\u001B[49m\n\u001B[1;32m   1336\u001B[0m \u001B[43m            \u001B[49m\u001B[43ma\u001B[49m\n\u001B[1;32m   1337\u001B[0m \u001B[43m            \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43ma\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_iter_next_step\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m   1338\u001B[0m \u001B[43m                \u001B[49m\u001B[43mname_to_tool_map\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1339\u001B[0m \u001B[43m                \u001B[49m\u001B[43mcolor_mapping\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1340\u001B[0m \u001B[43m                \u001B[49m\u001B[43minputs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1341\u001B[0m \u001B[43m                \u001B[49m\u001B[43mintermediate_steps\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1342\u001B[0m \u001B[43m                \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1343\u001B[0m \u001B[43m            \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m   1344\u001B[0m \u001B[43m        \u001B[49m\u001B[43m]\u001B[49m\n\u001B[1;32m   1345\u001B[0m     )\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain/agents/agent.py:1363\u001B[0m, in \u001B[0;36mAgentExecutor._iter_next_step\u001B[0;34m(self, name_to_tool_map, color_mapping, inputs, intermediate_steps, run_manager)\u001B[0m\n\u001B[1;32m   1360\u001B[0m     intermediate_steps \u001B[38;5;241m=\u001B[39m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_prepare_intermediate_steps(intermediate_steps)\n\u001B[1;32m   1362\u001B[0m     \u001B[38;5;66;03m# Call the LLM to see what to do.\u001B[39;00m\n\u001B[0;32m-> 1363\u001B[0m     output \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43m_action_agent\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mplan\u001B[49m\u001B[43m(\u001B[49m\n\u001B[1;32m   1364\u001B[0m \u001B[43m        \u001B[49m\u001B[43mintermediate_steps\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1365\u001B[0m \u001B[43m        \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43mrun_manager\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mget_child\u001B[49m\u001B[43m(\u001B[49m\u001B[43m)\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mif\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mrun_manager\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;28;43;01melse\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m,\u001B[49m\n\u001B[1;32m   1366\u001B[0m \u001B[43m        \u001B[49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[38;5;241;43m*\u001B[39;49m\u001B[43minputs\u001B[49m\u001B[43m,\u001B[49m\n\u001B[1;32m   1367\u001B[0m \u001B[43m    \u001B[49m\u001B[43m)\u001B[49m\n\u001B[1;32m   1368\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m OutputParserException \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m   1369\u001B[0m     \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28misinstance\u001B[39m(\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mhandle_parsing_errors, \u001B[38;5;28mbool\u001B[39m):\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain/agents/agent.py:464\u001B[0m, in \u001B[0;36mRunnableAgent.plan\u001B[0;34m(self, intermediate_steps, callbacks, **kwargs)\u001B[0m\n\u001B[1;32m    456\u001B[0m final_output: Any \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[1;32m    457\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mstream_runnable:\n\u001B[1;32m    458\u001B[0m     \u001B[38;5;66;03m# Use streaming to make sure that the underlying LLM is invoked in a\u001B[39;00m\n\u001B[1;32m    459\u001B[0m     \u001B[38;5;66;03m# streaming\u001B[39;00m\n\u001B[0;32m   (...)\u001B[0m\n\u001B[1;32m    462\u001B[0m     \u001B[38;5;66;03m# Because the response from the plan is not a generator, we need to\u001B[39;00m\n\u001B[1;32m    463\u001B[0m     \u001B[38;5;66;03m# accumulate the output into final output and return that.\u001B[39;00m\n\u001B[0;32m--> 464\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mchunk\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43mself\u001B[39;49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mrunnable\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mstream\u001B[49m\u001B[43m(\u001B[49m\u001B[43minputs\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mconfig\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m{\u001B[49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[38;5;124;43mcallbacks\u001B[39;49m\u001B[38;5;124;43m\"\u001B[39;49m\u001B[43m:\u001B[49m\u001B[43m \u001B[49m\u001B[43mcallbacks\u001B[49m\u001B[43m}\u001B[49m\u001B[43m)\u001B[49m\u001B[43m:\u001B[49m\n\u001B[1;32m    465\u001B[0m \u001B[43m        \u001B[49m\u001B[38;5;28;43;01mif\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mfinal_output\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01mis\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43;01mNone\u001B[39;49;00m\u001B[43m:\u001B[49m\n\u001B[1;32m    466\u001B[0m \u001B[43m            \u001B[49m\u001B[43mfinal_output\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m \u001B[49m\u001B[43mchunk\u001B[49m\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:3407\u001B[0m, in \u001B[0;36mRunnableSequence.stream\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m   3401\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mstream\u001B[39m(\n\u001B[1;32m   3402\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m   3403\u001B[0m     \u001B[38;5;28minput\u001B[39m: Input,\n\u001B[1;32m   3404\u001B[0m     config: Optional[RunnableConfig] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m   3405\u001B[0m     \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: Optional[Any],\n\u001B[1;32m   3406\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Iterator[Output]:\n\u001B[0;32m-> 3407\u001B[0m     \u001B[38;5;28;01myield from\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mtransform(\u001B[38;5;28miter\u001B[39m([\u001B[38;5;28minput\u001B[39m]), config, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:3394\u001B[0m, in \u001B[0;36mRunnableSequence.transform\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m   3388\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mtransform\u001B[39m(\n\u001B[1;32m   3389\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m   3390\u001B[0m     \u001B[38;5;28minput\u001B[39m: Iterator[Input],\n\u001B[1;32m   3391\u001B[0m     config: Optional[RunnableConfig] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m   3392\u001B[0m     \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: Optional[Any],\n\u001B[1;32m   3393\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Iterator[Output]:\n\u001B[0;32m-> 3394\u001B[0m     \u001B[38;5;28;01myield from\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_transform_stream_with_config(\n\u001B[1;32m   3395\u001B[0m         \u001B[38;5;28minput\u001B[39m,\n\u001B[1;32m   3396\u001B[0m         \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_transform,\n\u001B[1;32m   3397\u001B[0m         patch_config(config, run_name\u001B[38;5;241m=\u001B[39m(config \u001B[38;5;129;01mor\u001B[39;00m {})\u001B[38;5;241m.\u001B[39mget(\u001B[38;5;124m\"\u001B[39m\u001B[38;5;124mrun_name\u001B[39m\u001B[38;5;124m\"\u001B[39m) \u001B[38;5;129;01mor\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mname),\n\u001B[1;32m   3398\u001B[0m         \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs,\n\u001B[1;32m   3399\u001B[0m     )\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:2197\u001B[0m, in \u001B[0;36mRunnable._transform_stream_with_config\u001B[0;34m(self, input, transformer, config, run_type, **kwargs)\u001B[0m\n\u001B[1;32m   2195\u001B[0m \u001B[38;5;28;01mtry\u001B[39;00m:\n\u001B[1;32m   2196\u001B[0m     \u001B[38;5;28;01mwhile\u001B[39;00m \u001B[38;5;28;01mTrue\u001B[39;00m:\n\u001B[0;32m-> 2197\u001B[0m         chunk: Output \u001B[38;5;241m=\u001B[39m context\u001B[38;5;241m.\u001B[39mrun(\u001B[38;5;28mnext\u001B[39m, iterator)  \u001B[38;5;66;03m# type: ignore\u001B[39;00m\n\u001B[1;32m   2198\u001B[0m         \u001B[38;5;28;01myield\u001B[39;00m chunk\n\u001B[1;32m   2199\u001B[0m         \u001B[38;5;28;01mif\u001B[39;00m final_output_supported:\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:3357\u001B[0m, in \u001B[0;36mRunnableSequence._transform\u001B[0;34m(self, input, run_manager, config, **kwargs)\u001B[0m\n\u001B[1;32m   3354\u001B[0m     \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m   3355\u001B[0m         final_pipeline \u001B[38;5;241m=\u001B[39m step\u001B[38;5;241m.\u001B[39mtransform(final_pipeline, config)\n\u001B[0;32m-> 3357\u001B[0m \u001B[38;5;28;01myield from\u001B[39;00m final_pipeline\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:1413\u001B[0m, in \u001B[0;36mRunnable.transform\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m   1410\u001B[0m final: Input\n\u001B[1;32m   1411\u001B[0m got_first_val \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mFalse\u001B[39;00m\n\u001B[0;32m-> 1413\u001B[0m \u001B[43m\u001B[49m\u001B[38;5;28;43;01mfor\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43michunk\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;129;43;01min\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;28;43minput\u001B[39;49m\u001B[43m:\u001B[49m\n\u001B[1;32m   1414\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;66;43;03m# The default implementation of transform is to buffer input and\u001B[39;49;00m\n\u001B[1;32m   1415\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;66;43;03m# then call stream.\u001B[39;49;00m\n\u001B[1;32m   1416\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;66;43;03m# It'll attempt to gather all input into a single chunk using\u001B[39;49;00m\n\u001B[1;32m   1417\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;66;43;03m# the `+` operator.\u001B[39;49;00m\n\u001B[1;32m   1418\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;66;43;03m# If the input is not addable, then we'll assume that we can\u001B[39;49;00m\n\u001B[1;32m   1419\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;66;43;03m# only operate on the last chunk,\u001B[39;49;00m\n\u001B[1;32m   1420\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;66;43;03m# and we'll iterate until we get to the last chunk.\u001B[39;49;00m\n\u001B[1;32m   1421\u001B[0m \u001B[43m    \u001B[49m\u001B[38;5;28;43;01mif\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[38;5;129;43;01mnot\u001B[39;49;00m\u001B[43m \u001B[49m\u001B[43mgot_first_val\u001B[49m\u001B[43m:\u001B[49m\n\u001B[1;32m   1422\u001B[0m \u001B[43m        \u001B[49m\u001B[43mfinal\u001B[49m\u001B[43m \u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43m \u001B[49m\u001B[43michunk\u001B[49m\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:5561\u001B[0m, in \u001B[0;36mRunnableBindingBase.transform\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m   5555\u001B[0m \u001B[38;5;28;01mdef\u001B[39;00m \u001B[38;5;21mtransform\u001B[39m(\n\u001B[1;32m   5556\u001B[0m     \u001B[38;5;28mself\u001B[39m,\n\u001B[1;32m   5557\u001B[0m     \u001B[38;5;28minput\u001B[39m: Iterator[Input],\n\u001B[1;32m   5558\u001B[0m     config: Optional[RunnableConfig] \u001B[38;5;241m=\u001B[39m \u001B[38;5;28;01mNone\u001B[39;00m,\n\u001B[1;32m   5559\u001B[0m     \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs: Any,\n\u001B[1;32m   5560\u001B[0m ) \u001B[38;5;241m-\u001B[39m\u001B[38;5;241m>\u001B[39m Iterator[Output]:\n\u001B[0;32m-> 5561\u001B[0m     \u001B[38;5;28;01myield from\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mbound\u001B[38;5;241m.\u001B[39mtransform(\n\u001B[1;32m   5562\u001B[0m         \u001B[38;5;28minput\u001B[39m,\n\u001B[1;32m   5563\u001B[0m         \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39m_merge_configs(config),\n\u001B[1;32m   5564\u001B[0m         \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39m{\u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39m\u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mkwargs, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs},\n\u001B[1;32m   5565\u001B[0m     )\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/runnables/base.py:1431\u001B[0m, in \u001B[0;36mRunnable.transform\u001B[0;34m(self, input, config, **kwargs)\u001B[0m\n\u001B[1;32m   1428\u001B[0m             final \u001B[38;5;241m=\u001B[39m ichunk\n\u001B[1;32m   1430\u001B[0m \u001B[38;5;28;01mif\u001B[39;00m got_first_val:\n\u001B[0;32m-> 1431\u001B[0m     \u001B[38;5;28;01myield from\u001B[39;00m \u001B[38;5;28mself\u001B[39m\u001B[38;5;241m.\u001B[39mstream(final, config, \u001B[38;5;241m*\u001B[39m\u001B[38;5;241m*\u001B[39mkwargs)\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:420\u001B[0m, in \u001B[0;36mBaseChatModel.stream\u001B[0;34m(self, input, config, stop, **kwargs)\u001B[0m\n\u001B[1;32m    413\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m    414\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_llm_error(\n\u001B[1;32m    415\u001B[0m         e,\n\u001B[1;32m    416\u001B[0m         response\u001B[38;5;241m=\u001B[39mLLMResult(\n\u001B[1;32m    417\u001B[0m             generations\u001B[38;5;241m=\u001B[39m[[generation]] \u001B[38;5;28;01mif\u001B[39;00m generation \u001B[38;5;28;01melse\u001B[39;00m []\n\u001B[1;32m    418\u001B[0m         ),\n\u001B[1;32m    419\u001B[0m     )\n\u001B[0;32m--> 420\u001B[0m     \u001B[38;5;28;01mraise\u001B[39;00m e\n\u001B[1;32m    421\u001B[0m \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m    422\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_llm_end(LLMResult(generations\u001B[38;5;241m=\u001B[39m[[generation]]))\n",
      "File \u001B[0;32m~/code/langchainv3/.venv/lib/python3.11/site-packages/langchain_core/language_models/chat_models.py:412\u001B[0m, in \u001B[0;36mBaseChatModel.stream\u001B[0;34m(self, input, config, stop, **kwargs)\u001B[0m\n\u001B[1;32m    410\u001B[0m         \u001B[38;5;28;01melse\u001B[39;00m:\n\u001B[1;32m    411\u001B[0m             generation \u001B[38;5;241m+\u001B[39m\u001B[38;5;241m=\u001B[39m chunk\n\u001B[0;32m--> 412\u001B[0m     \u001B[38;5;28;01massert\u001B[39;00m generation \u001B[38;5;129;01mis\u001B[39;00m \u001B[38;5;129;01mnot\u001B[39;00m \u001B[38;5;28;01mNone\u001B[39;00m\n\u001B[1;32m    413\u001B[0m \u001B[38;5;28;01mexcept\u001B[39;00m \u001B[38;5;167;01mBaseException\u001B[39;00m \u001B[38;5;28;01mas\u001B[39;00m e:\n\u001B[1;32m    414\u001B[0m     run_manager\u001B[38;5;241m.\u001B[39mon_llm_error(\n\u001B[1;32m    415\u001B[0m         e,\n\u001B[1;32m    416\u001B[0m         response\u001B[38;5;241m=\u001B[39mLLMResult(\n\u001B[1;32m    417\u001B[0m             generations\u001B[38;5;241m=\u001B[39m[[generation]] \u001B[38;5;28;01mif\u001B[39;00m generation \u001B[38;5;28;01melse\u001B[39;00m []\n\u001B[1;32m    418\u001B[0m         ),\n\u001B[1;32m    419\u001B[0m     )\n",
      "\u001B[0;31mAssertionError\u001B[0m: "
     ]
    }
   ],
   "source": [
    "agent.invoke({\"input\": \"连续两个月都下订单的客户有哪些?\"})"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2024-11-11T06:53:10.247998Z",
     "start_time": "2024-11-11T06:53:07.997271Z"
    }
   },
   "id": "a2a1157923c5da39",
   "execution_count": 46
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
